<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2010-04-22
 * |Update: 2011-01-07
 * -+-----------------------------------------
 *
 * 模型基础类 ，所有的Model层都应继承此类
 * @author jinke
 */
class Model extends AdvModel
{


	/**
	 * 数据库配置资料数组
	 * @var array
	 */
	protected  $dbArray = array();

	/**
	 * 是否开启主从库模式 默认为 false
	 * @var bool
	 */
	protected $open_slave = false;



	/**
	 * 从库连接
	 * @var object
	 */
	protected $slave_db = null;
	
	/**
	 * 查询的数据是否返回实体对象
	 * @var bool
	 */
	protected $entity_data = false;

	/**
	 * 需要查询的列
	 * @var string
	 */
	protected $adv_find = '*';

	/**
	 * 查询条件
	 * @var string
	 */
	protected $adv_where = '';

	/**
	 *  Mysql in 语句条件
	 * @var string
	 */
	protected $adv_in = '';

	/**
	 * Mysql not in 语句条件
	 * @var string
	 */
	protected $adv_not_in = '';

	/**
	 * 排序方式
	 * @var string
	 */
	protected $adv_order = '';

	/**
	 * 分组
	 * @var string
	 */
	protected $adv_group = '';

	/**
	 * 获取指定长度的资料  例 0,100
	 * @var string
	 */
	protected $adv_limit = '';


	public $show_sql = '';


	/**
	 * 构造函数 主要用于初始化分配数据库连接资料
	 * @access public
	 * @param mixed $table_name 表名称或MODEL对象[可选]
	 * @param string $app_name 当前所在的应用程序名称
	 */
	public function __construct($table_name = '',$app_name='')
	{
		
		if(is_object($table_name))
		{
			$table_name = str_replace('_Model','',get_class($table_name));
			Debug::initClass('<b>'.$table_name.'.model.php</b>');
		}
		else
			//清除Model标记
			$table_name = str_replace('Model','',$table_name);

		//设置表名称
		if(empty($this->_tableName))
		{
			if(!empty($table_name))
				$this->_tableName = strtolower($table_name);
		}
		
		//Debug::initClass('model.class.php - '.get_class($this));

	}
	
	
	
	/**
	 * 检查数据库配置资料是否正确
	 */
	protected function checkDBConfig()
	{
		//获取所有的数据库
		$dbs = Config::get('database');
		if(!isset($dbs['db_prefix']))
			message_error('Config Error','数据库配置错误，确少db_prefix',BASE_DIR.'config.inc.php');
		if(!isset($dbs[$this->_dbType]) )
			message_error('Config Error','数据库配置错误，确少'.$this->_dbType,BASE_DIR.'config.inc.php');
		return $dbs;
	}
	
	
	/**
	 * 获取数据库连接
	 * @access public
	 * @param string $dbName 数据库名称
	 * @return void
	 */
	public function getConnect($dbName = null)
	{
		$dbs = $this->checkDBConfig();

		$this->open_slave = $dbs['open_slave'];
		$dbDriveClassName = '';
		if ($this->_dbType == MODEL_DB_TYPE_MYSQL){
			require_once FRAMEWORK_LIB_DIR.'MysqlDB.class.php';
			$dbDriveClassName = 'MysqlDB';
		}elseif ($this->_dbType == MODEL_DB_TYPE_MONGODB){
			require_once FRAMEWORK_LIB_DIR.'MongoDB.class.php';
			$dbDriveClassName = 'MongoDB';
		}
		if ($dbName==null)
			$dbName = $this->_dbName;

		//如果开启主从模式
		if ($this->open_slave)
		{
			//随机获取一个从数据库连接
			$slave = array_values($dbs['slave']);;
			$index=rand(0, count($slave)-1);
			$slave =$slave[$index];

			if (!isset($dbs[$this->_dbType][$slave]))
				message_error('Config Error','没有找到从库：'.$slave.' 的配置资料！',BASE_DIR.'config.inc.php');

			$slave_connect  = $dbs[$this->_dbType][$slave];
			$this->slave_db = new $dbDriveClassName($slave_connect,$dbName, $this->_tableName);

		}
		//设置主数据库（可写）
		if (!isset($dbs[$this->_dbType][$dbs['master']]))
			message_error('Config Error','没有找到主库：'.$dbs['master'].' 的配置资料！',BASE_DIR.'config.inc.php');
		$master_connect  = $dbs[$this->_dbType][$dbs['master']];
		$this->master_db = new $dbDriveClassName($master_connect,$dbName, $this->_tableName);

	}
	
	

	/**
	 * 开启主从库模式时，自动分配数据库连接
	 * @access private
	 * @param string 查询类型
	 */
	protected  function setDbConnect($type='select')
	{
		if (!$this->open_slave)
		{
			$this->_db = $this->master_db;
			return;
		}
		if ($type=='insert'||$type=='update'||$type=='remove')
			$this->_db = $this->master_db;
		else
			$this->_db = $this->slave_db;
	
	}


   /**
    * 获取&设置model 默认所需要的数据库名称
	* @access private
	* @param string $appName 应用程序名称
	* @return void
	*/
	protected function getAppDefaultDataBaseName($appName)
	{
		//如果实例化的MODEL 没有指定设置 $this->_dbName 则从记录中分析所在的APP_NAME
		if (Functions::REG('M_FUN_APP_NAME') && $appName == '')
		{ 
			$appName = Functions::REG('M_FUN_APP_NAME');
			$t = explode(',', $appName);
			$appName = $t[count($t)-1];
			unset($t[count($t)-1]);
			if (count($t)==0)
				Functions::RES('M_FUN_APP_NAME', false);
			else 
				Functions::RES('M_FUN_APP_NAME', implode(',', $t));
			
		}

		if($this->_dbName=='' && $appName!='')
		{
			if($dbKey=  Functions::getAppConfig($appName.'.common.default_dbkey'))
			{ 
				
				$this->_dbName = DBTool::getDBName($dbKey);
			}
			else 
			{
				//输出错误信息
				$str= $appName.'.'.strtolower(str_replace('_Model','',get_class($this)));
				el_ModelInitDbNameNullAndConfigError($str);
			}
		}
	}
	
	/**
	 * 设置最终将要返回的查询资料
	 * @param mixed $data
	 */
	protected  function setSelectDataType(&$data)
	{
		if ($this->entity_data === true)
			return DBTool::toEntityObject($data, $this);
		return $data;
	}
	
	/**
	 * 获取主键名称
	 * @access public
	 * @return string
	 */
	public function getPk()
	{
		return $this->_pk;
	}
	
}
?>